package com.zx.cloud.config;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.zx.cloud.common.auth0.jwt.TokenGenerator;
import com.zx.cloud.common.auth0.jwt.interfaces.Claim;
import com.zx.cloud.common.filter.IgnoreAuth;
import com.zx.cloud.common.filter.MagicConstants;
import com.zx.cloud.common.filter.MagicPermission;
import com.zx.cloud.controller.StatusCode;
import com.zx.cloud.domain.Resource;
import com.zx.cloud.model.response.ErrorEntity;
import com.zx.cloud.util.CookieManager;
import com.zx.cloud.util.ServletUtil;

public class PermissionAnnotationInterceptor extends HandlerInterceptorAdapter {

    private final Pattern allowedMethods = Pattern.compile("^(POST)$");

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
        	String  uri=request.getServletPath();
			if(uri.equals("/v2/api-docs")||uri.equals("/swagger-resources")){
				return true;
			}
			System.out.println(ServletUtil.toString(request));
        	HandlerMethod methodHandler = (HandlerMethod) handler;
            String token = request.getHeader(MagicConstants.AUTH_TOKEN);
            if (StringUtils.isEmpty(token)) {
                token = request.getParameter(MagicConstants.AUTH_TOKEN);
            }
            if (StringUtils.isEmpty(token)) {
                token = new CookieManager(request, null).getCookie(MagicConstants.AUTH_TOKEN);
            }
            //登录判断
            IgnoreAuth annotation = methodHandler.getMethodAnnotation(IgnoreAuth.class);
            // 如果有@IgnoreAuth注解，则不验证token
            if (annotation == null && (StringUtils.isEmpty(token))) {
            	System.out.println("-----------1-----------annotation--------------------["+uri+"]");
                writeMessage(request, response);
                return false;
            }
            Map<String, Claim> datas = null;
            if (StringUtils.isNotEmpty(token)) {
                try {
                    datas = TokenGenerator.getClaims(token);        //权限资源信息
                } catch (Exception e) {
                    e.printStackTrace();
                    ServletUtil.writeJson(new ErrorEntity(StatusCode.TOKEN_EXPIRED), response);//token过期
                    return false;
                }
                String userId = datas.get(MagicConstants.SESSION_USER_ID).asString();
                if (annotation != null && (StringUtils.isEmpty(userId))) {
                	System.out.println("-----------2-----------annotation--------------------["+uri+"]");
                    writeMessage(request, response);
                    return false;
                }
            }
            //有无权限访问链接
            MagicPermission magicPermission = methodHandler.getMethodAnnotation(MagicPermission.class);
            if (null != magicPermission) {
            	List<Resource> resources = datas.get(MagicConstants.SESSION_USER_PERMISSIONS).asList(Resource.class);
                if (StringUtils.isEmpty(token)) {
                	System.out.println("-----------3-----------annotation--------------------["+uri+"]");
                    writeMessage(request, response);
                    return false;
                }
                // 检查是否有权限访问
                boolean hasPermission = false;
                Iterator<Resource> iterator = resources.iterator();
                while (iterator.hasNext()) {
                    Resource resource = iterator.next();
                    if (("/" +resource.getUrl()).equals(uri)) {        //根据请求链接判断
                        hasPermission = true;
                    }
                }
                if (!hasPermission) {
                    System.err.println("--------无权限------[" + request.getServletPath() + "]");
                    writeMessage(request, response);
                    return false;
                }
            }
        }
        return true;
    }

    private void writeMessage(HttpServletRequest request, HttpServletResponse response) throws IOException {
//        if (allowedMethods.matcher(request.getMethod().toUpperCase()).matches()) {
            response.setHeader("sessionstatus", "timeout");
            ServletUtil.writeJson(new ErrorEntity(StatusCode.INVALID_ACCESS), response);
//        } else {
//            response.sendRedirect(request.getContextPath() + "/login");
//        }
    }

}
